<template>
  <div>
    <div class="chat-container">
      <!-- 左侧面板 -->
      <div class="left-panel">
        <div class="header">
          <div class="app-name">
            <font-awesome-icon icon="brain" />
            <span style="margin-left: 10px"
              >&nbsp;&nbsp;&nbsp;&nbsp;精睿灵犀</span
            >
          </div>
          <div class="template-icon" @mouseover="showTemplateOverlay">
            <font-awesome-icon icon="layer-group" />
          </div>
        </div>

        <div class="button-container">
          <button class="oval-button" @click="showCreateSessionDialog">
            <i class="fas fa-plus"></i> 新建会话
          </button>
        </div>

        <div class="session-container">
          <div class="session-title">历史会话</div>
          <ul class="session-list">
            <li v-for="(session, index) in sortedSessions" :key="session.id">
              <div
                class="session-item"
                :class="{ active: currentSessionId === session.id }"
                @click="switchSession(session.id)"
              >
                <div class="session-name">{{ session.description }}</div>
                <el-dropdown
                  trigger="click"
                  @command="handleCommand(session.id, $event)"
                >
                  <span class="session-actions">
                    <i class="el-icon-more"></i>
                  </span>
                  <el-dropdown-menu slot="dropdown">
                    <el-dropdown-item command="edit">修改</el-dropdown-item>
                    <el-dropdown-item command="delete">删除</el-dropdown-item>
                  </el-dropdown-menu>
                </el-dropdown>
              </div>
            </li>
          </ul>
        </div>
      </div>

      <!-- 模板管理浮层 -->
      <div
        class="template-overlay"
        :class="{ visible: templateOverlayVisible }"
        @mouseleave="hideTemplateOverlay"
      >
        <div class="template-header">
          <div class="template-title">模板管理</div>
          <i class="el-icon-close" @click="hideTemplateOverlay"></i>
        </div>

        <div class="template-actions">
          <div class="template-button" @click="createTemplate">
            <div class="template-icon-sm">
              <font-awesome-icon icon="file-alt" color="#4285F4" />
            </div>
            <div>
              <span>新建模板</span>
              <p>在OnlyOffice中创建新模板</p>
            </div>
          </div>

          <div class="template-button" @click="viewTemplates">
            <div class="template-icon-sm">
              <font-awesome-icon icon="folder-open" color="#4285F4" />
            </div>
            <div>
              <span>查看模板</span>
              <p>浏览已有模板并进行管理</p>
            </div>
          </div>
        </div>

        <div class="template-list">
          <div class="template-title" style="margin-bottom: 15px">最近模板</div>
          <div v-if="templates.length > 0">
            <div
              v-for="template in templates"
              :key="template.id"
              class="template-item"
              @click="editTemplate(template)"
            >
              <div class="template-icon-sm">
                <font-awesome-icon
                  :icon="getFileIcon(template.fileType)"
                  :style="{ color: getTemplateColor(template.fileType) }"
                />
              </div>
              <div class="template-info">
                <div class="template-name">{{ template.name }}</div>
                <div class="template-date">
                  最后修改: {{ parseTime(template.updateTime) }}
                </div>
              </div>
            </div>
          </div>
          <div v-else class="placeholder-text">暂无最近使用的模板</div>
        </div>
      </div>

      <!-- 右侧聊天区域 -->
      <div class="right-panel">
        <!-- 1. 默认聊天区域 -->
        <div v-if="currentView === 'chat'" class="chat-wrapper">
          <div class="chat-header">
            <div class="chat-title">{{ currentSessionName }}</div>
          </div>

          <div class="chat-content" ref="messageList">
            <div
              class="message"
              v-for="(message, index) in messages"
              :key="index"
              :class="{
                'message-bot': message.type === 'bot',
                'message-user': message.type === 'user',
                'message-loading': message.type === 'loading',
              }"
            >
              <!-- 加载消息 -->
              <template v-if="message.type === 'loading'">
                <div class="avatar">
                  <font-awesome-icon icon="robot" color="#4285F4" />
                </div>
                <div class="message-content">
                  <div class="text loading-indicator">
                    正在思考
                    <span class="dot-flash"></span>
                    <span class="dot-flash"></span>
                    <span class="dot-flash"></span>
                  </div>
                </div>
              </template>

              <div v-if="message.type === 'bot'" class="avatar">
                <font-awesome-icon icon="robot" color="#4285F4" />
              </div>

              <div
                class="message-content"
                v-if="message.Mstype != 'chart' && message.type !== 'loading'"
              >
                <div
                  class="text"
                  v-if="message.type === 'bot'"
                  v-html="message.content"
                  :class="{ typing: message.typing }"
                ></div>
                <div class="text" v-else>{{ message.content }}</div>
              </div>

              <!-- <div v-if="message.type === 'user'" class="avatar">
                <i class="fas fa-user" style="color: #1e5799"></i>
              </div> -->
              
              <div v-if="message.type === 'user'" class="avatar">
                <img :src="userAvatar" alt="用户头像" class="avatar-image" />
              </div>

              <!-- 图表消息 -->
              <div v-if="message.Mstype === 'chart'" class="message chart">
                <ChartRenderer
                  v-if="message.chartConfig"
                  :config="message.chartConfig"
                />
                <div class="chart-caption">{{ message.caption }}</div>
              </div>

              <!-- 文件消息 -->
              <div v-if="message.Mstype === 'file'" class="file-info">
                <i class="el-icon-document file-icon"></i>
                <span class="file-name">{{ message.fileInfo.name }}</span>
                <a
                  :href="message.fileInfo.url"
                  :download="message.fileInfo.name"
                >
                  <el-button class="file-action" size="small" type="text">
                    下载
                  </el-button>
                </a>
              </div>

              <!-- 图片消息 -->
              <div v-if="message.Mstype === 'image'" class="image-preview">
                <img
                  :src="message.fileInfo.url"
                  alt="image preview"
                  style="max-width: 200px; max-height: 200px; cursor: pointer"
                  @click="previewImage(message.fileInfo)"
                />
              </div>
            </div>
          </div>

          <div class="chat-input">
            <div class="input-area" @keyup.enter="sendMessage">
              <div class="upload-area">
                <div class="upload-container">
                  <!-- 上传文件 -->
                  <el-upload
                    ref="upload"
                    action="#"
                    :before-upload="handleBeforeUpload"
                    :show-file-list="false"
                  >
                    <el-button class="upload-btn">
                      <!-- <img :src="require('@/assets/images/uploadFiles.png')" style="margin-top: 20px;" /> -->
                      <!-- <font-awesome-icon icon="file-upload" class="upload-icon" /> -->
                    </el-button>
                  </el-upload>

                  <!-- 上传图片 -->
                  <!-- <el-upload
                  ref="imageUpload"
                  action="#"
                  :before-upload="handleImageBeforeUpload"
                  :show-file-list="false"
                  accept="image/*"
                >
                  <el-button class="upload-btn" >
                    <font-awesome-icon icon="image" class="upload-icon" />
                  </el-button>
                </el-upload> -->
                </div>

                <!-- 文件列表展示区域 -->
                <div class="files-grid">
                  <transition-group
                    name="file-list"
                    tag="div"
                    class="grid-container"
                  >
                    <div
                      v-for="file in [...uploadFileList, ...imageFileList]"
                      :key="file.name"
                      class="grid-item"
                    >
                      <div class="file-box">
                        <div class="file-icon">
                          <i
                            :class="[
                              file.type && file.type.startsWith('image/')
                                ? 'el-icon-picture-outline'
                                : 'el-icon-document',
                            ]"
                          ></i>
                        </div>
                        <div class="file-name" :title="file.name">
                          {{ file.name }}
                        </div>
                        <div class="file-actions">
                          <i
                            class="el-icon-close"
                            @click="
                              file.type && file.type.startsWith('image/')
                                ? handleImageRemove(file)
                                : handleFileRemove(file)
                            "
                          ></i>
                        </div>
                      </div>
                    </div>
                  </transition-group>
                </div>
              </div>

              <div class="input-row">
                <textarea
                  v-model="inputMessage"
                  placeholder="输入您的问题或需求..."
                  :rows="3"
                  resize="none"
                ></textarea>
                <button
                  class="send-button"
                  @click="sendMessage"
                  :loading="sending"
                >
                  <font-awesome-icon
                    style="
                      font-size: 30px;
                      color: #409eff;
                      background-color: white;
                    "
                    icon="paper-plane"
                  />
                </button>
              </div>
            </div>
          </div>
        </div>

        <!-- 2. 模板类型选择组件 -->
        <div v-if="currentView === 'templateType'">
          <div class="component-header">
            <el-button @click="currentView = 'chat'" class="back-btn">
              <i class="el-icon-arrow-left"></i>返回
            </el-button>
            <!-- <h3>选择模板类型</h3> -->
          </div>
          <!-- 引入模板类型选择组件 -->
          <template-type-select
            @selectType="handleTypeSelect"
            @back="currentView = 'chat'"
          />
        </div>

        <!-- 3. onlyOffice编辑组件 -->
        <div v-if="currentView === 'onlyOffice'">
          <div class="component-header">
            <el-button @click="currentView = 'templateType'" class="back-btn">
              <i class="el-icon-arrow-left"></i> 返回类型选择
            </el-button>
            <el-button @click="currentView = 'chat'" class="back-btn">
              <i class="el-icon-home"></i> 首页
            </el-button>
            <!-- <h3>创建{{ (currentDocType && currentDocType.name) || "" }}</h3> -->
          </div>

          <!-- 引入OnlyOffice编辑组件 -->
          <only-office-template
            style="height: 780px"
            :doc-type="currentDocType"
            @saveSuccess="handleTemplateSave"
          />
        </div>

        <!-- 4. 模板列表视图 -->
        <div v-if="currentView === 'templateList'" class="template-list-view">
          <template-list-view
            ref="templateListRef"
            @back="handleTemplateListBack"
            @createNew="handleCreateFromList"
            @editTemplate="handleEditFromList"
            @createNewTemplate="handleCreateNewFromList"
          ></template-list-view>
        </div>

        <!-- 模板名称输入弹框 -->
        <el-dialog
          title="输入模板名称"
          :visible.sync="showTemplateNameDialog"
          width="30%"
        >
          <el-input
            v-model="templateName"
            placeholder="请输入模板名称"
            maxlength="50"
          ></el-input>
          <span slot="footer" class="dialog-footer">
            <el-button
              class="dialog-btn dialog-btn-primary"
              @click="showTemplateNameDialog = false"
              >取消</el-button
            >
            <el-button
              class="dialog-btn dialog-btn-primary"
              @click="confirmTemplateName"
              >确定</el-button
            >
          </span>
        </el-dialog>
      </div>
    </div>

    <!-- 新建会话弹框 -->
    <el-dialog
      title="新建会话"
      :visible.sync="createSessionDialogVisible"
      width="30%"
      @close="resetSessionName"
    >
      <el-input v-model="sessionName" placeholder="请输入会话名称"></el-input>
      <span slot="footer" class="dialog-footer">
        <!-- 取消按钮 -->
        <el-button
          class="dialog-btn dialog-btn-primary"
          @click="createSessionDialogVisible = false"
          >取消</el-button
        >
        <!-- 确定按钮（强调色） -->
        <el-button
          class="dialog-btn dialog-btn-primary"
          type="primary"
          @click="createSession(0)"
          >确定</el-button
        >
      </span>
    </el-dialog>

    <!-- 修改会话弹框 -->
    <el-dialog
      title="修改会话"
      :visible.sync="updateSessionDialogVisible"
      width="30%"
      @close="resetSessionName"
    >
      <el-input v-model="sessionName" placeholder="请输入会话名称"></el-input>
      <span slot="footer" class="dialog-footer">
        <el-button
          class="dialog-btn dialog-btn-primary"
          @click="updateSessionDialogVisible = false"
          >取消</el-button
        >
        <el-button
          class="dialog-btn dialog-btn-primary"
          type="primary"
          @click="createSession(1)"
          >确定</el-button
        >
      </span>
    </el-dialog>

    <!-- 通知消息 -->
    <div class="floating-notification" v-if="notificationVisible">
      <div class="notification-icon">
        <i class="fas fa-check-circle"></i>
      </div>
      <div class="notification-content">
        <h3>模板创建成功</h3>
        <p>新的销售报告模板已保存到模板库</p>
      </div>
      <div class="close-notification" @click="notificationVisible = false">
        <i class="fas fa-times"></i>
      </div>
    </div>
  </div>
</template>

<script>
import {
  createSession,
  getSessions,
  getChatList,
  delSession,
  Chat,
  updataSession,
} from "@/api/chat/chat";
import { getToken } from "@/utils/auth";
import ChartRenderer from "@/components/ChartRenderer/ChartRenderer";
import OnlyOfficeTemplate from "@/views/intelligence/chat/window/onlyOfficeTemplate.vue";
import TemplateTypeSelect from "@/views/intelligence/chat/window/templateTypeSelect.vue";
import TemplateListView from "@/views/intelligence/chat/window/templateListView.vue";
import { getRecentTemplates } from "@/api/zhishiku/template";

export default {
  name: "chatWindow",
  components: {
    ChartRenderer,
    TemplateTypeSelect, // 模板选择
    OnlyOfficeTemplate,
    TemplateListView,
  },
  data() {
    return {
      //最近模板刷新
      templatesCache: null,
      templatesCacheTime: 0,
      cacheDuration: 60 * 1000, // 缓存有效期1分钟

      currentView: "chat",
      // 当前选择的文档类型
      currentDocType: null,

      // 模板名称输入弹框
      tempSelectedDocType: null, // 临时存储选中的模板类型
      showTemplateNameDialog: false, // 弹框显示状态
      templateName: "", // 用户输入的模板名称

      templateOverlayVisible: false,
      notificationVisible: false,
      currentSessionId: null,
      currentSessionName: "",
      sessions: [],
      templates: [], // 存储最近模板数据
      inputMessage: "",
      messages: [],
      userAvatar: require("@/assets/images/user.png"),
      // botAvatar: require("@/assets/images/profile.jpg"),
      createSessionDialogVisible: false,
      updateSessionDialogVisible: false,
      sessionName: "",
      delSe: [],
      editSessioinId: "",
      uploadedFiles: [],
      uploadFileUrl: "/dev-api/api/upload/file",
      uploadImageUrl: "/dev-api/api/upload/image",
      headers: {
        Authorization: "Bearer " + getToken(),
      },
      uploadFileList: [],
      imageFileList: [],
      uploadRetryCount: 0,
      maxRetries: 3,
      retryDelay: 1000,
      equipmentStats: null,
      faultAnalysis: null,
      failureStatistics: null,
      clusterAnalysis: null,
      controlChartData: null,
      faultDetails: null,
      dateRange: [],
      selectedDeviceType: null,
      uploadHeaders: {
        "X-Requested-With": "XMLHttpRequest",
        Authorization: "Bearer " + getToken(),
      },
      loading: false,
      sending: false,
    };
  },
  computed: {
    sortedSessions() {
      return this.sessions.slice().sort((a, b) => {
        if (a.id === this.currentSessionId) return -1;
        if (b.id === this.currentSessionId) return 1;
        return 0;
      });
    },
  },
  mounted() {
    this.getSessionList();
    // 页面加载时获取最近模板
    this.fetchRecentTemplates();
  },
  methods: {
    // 获取最近模板
    // 获取最近模板（带缓存）
    async fetchRecentTemplates(forceRefresh = false) {
      // 检查缓存是否有效
      const now = Date.now();
      if (
        !forceRefresh &&
        this.templatesCache &&
        now - this.templatesCacheTime < this.cacheDuration
      ) {
        this.templates = this.templatesCache;
        return Promise.resolve();
      }

      try {
        const response = await getRecentTemplates();
        if (response.code === 200) {
          this.templates = response.data || [];
          // 更新缓存
          this.templatesCache = this.templates;
          this.templatesCacheTime = now;
        } else {
          this.$message.error("获取最近模板失败：" + response.msg);
        }
      } catch (error) {
        console.error("获取最近模板请求失败", error);
        this.$message.error("获取最近模板时发生错误");
      }
    },
    // async fetchRecentTemplates() {
    //   try {
    //     const response = await getRecentTemplates();
    //     if (response.code === 200) {
    //       this.templates = response.data || [];
    //     } else {
    //       this.$message.error("获取最近模板失败：" + response.msg);
    //     }
    //   } catch (error) {
    //     console.error("获取最近模板请求失败", error);
    //     this.$message.error("获取最近模板时发生错误");
    //   }
    // },

    // 监听子组件事件：处理从模板列表页触发的“新建模板”事件
    handleCreateNewFromList() {
      // 切换到模板类型选择视图
      this.currentView = "templateType";
      console.log("从模板列表点击新建，切换到 templateType 视图");
    },

    // 处理模板类型选择
    handleTypeSelect(type) {
      console.log("父组件：接收到selectType事件，选中类型：", type);
      this.tempSelectedDocType = type; // 临时存储选中的类型
      this.showTemplateNameDialog = true;
      this.templateName = "";
    },

    // 切换到模板类型选择
    createTemplate() {
      this.hideTemplateOverlay();
      this.currentView = "templateType"; // 切换视图
      console.log("切换到模板类型选择页，currentView：", this.currentView);
    },
    // 确认模板名称（弹框确定按钮）
    confirmTemplateName() {
      if (!this.templateName.trim()) {
        this.$message.warning("请输入模板名称");
        return;
      }
      // 隐藏弹框，切换到编辑视图
      this.showTemplateNameDialog = false;
      this.currentDocType = this.tempSelectedDocType;
      // 将模板名称传递给编辑组件
      this.currentDocType.templateName = this.templateName;
      this.currentView = "onlyOffice";
    },

    // 处理模板保存成功
    handleTemplateSave() {
      this.notificationVisible = true;

      setTimeout(() => {
        this.currentView = "templateList"; // 切换到模板列表视图

        // 强制刷新模板列表（调用子组件方法）
        if (this.$refs.templateListRef) {
          this.$refs.templateListRef.fetchTemplates(true); // 传递true参数强制刷新
        }
        this.notificationVisible = false;
        this.currentView = "chat";
      }, 3000);
    },

    getFileIcon(fileType) {
      switch (fileType) {
        case "docx":
          return ["fas", "file-word"];
        case "xlsx":
          return ["fas", "file-excel"];
        case "pptx":
          return ["fas", "file-powerpoint"];
        default:
          return ["fas", "file"];
      }
    },
    getTemplateColor(fileType) {
      switch (fileType) {
        case "docx":
          return "#2c82e0";
        case "xlsx":
          return "#36b37e";
        case "pptx":
          return "#ff5630";
        default:
          return "#8993a4";
      }
    },

    showTemplateOverlay() {
      this.fetchRecentTemplates();
      this.templateOverlayVisible = true;
      console.log("浮层显示");
    },
    hideTemplateOverlay() {
      this.templateOverlayVisible = false;
      console.log("浮层隐藏");
    },
    viewTemplates() {
      this.hideTemplateOverlay(); // 关闭浮层
      this.currentView = "templateList"; // 切换到模板列表视图
    },

    // 从模板列表返回
    handleTemplateListBack() {
      this.currentView = "chat"; // 返回聊天视图
    },

    // 从列表页新建模板
    handleCreateFromList() {
      this.currentView = "templateType"; // 切换到类型选择
    },

    // 从列表页编辑模板
    handleEditFromList(template) {
      // 构建编辑所需的类型信息
      const docType = {
        id: template.documentType,
        name: template.name,
        fileType: template.fileType,
        documentType: template.documentType,
        templateId: template.id, // 传递模板ID用于编辑
        templateName: template.name, // 确保templateName存在
        category: template.category,
        filePath: template.filePath,
        isEdit: true, // 标记为编辑模式
        userName: template.userName,
      };

      // 添加默认值，防止未定义
      if (!docType.templateName) {
        docType.templateName = `模板_${template.id}`;
      }

      this.currentDocType = docType;
      this.currentView = "onlyOffice"; // 切换到编辑视图
    },

    editTemplate(template) {
      console.log("编辑模板:", template.name);
      this.hideTemplateOverlay();

      // 构建编辑所需的类型信息
      const docType = {
        id: template.documentType,
        name: template.name,
        fileType: template.fileType,
        documentType: template.documentType,
        templateId: template.id, // 传递模板ID用于编辑
        templateName: template.name, // 确保templateName存在
        category: template.category,
        filePath: template.filePath,
        isEdit: true, // 标记为编辑模式
        userName: template.userName,
      };

      // 添加默认值，防止未定义
      if (!docType.templateName) {
        docType.templateName = `模板_${template.id}`;
      }

      this.currentDocType = docType;
      this.currentView = "onlyOffice"; // 切换到编辑视图
    },
    // 显示新建会话对话框
    showCreateSessionDialog() {
      this.createSessionDialogVisible = true;
    },
    // 重置会话名称
    resetSessionName() {
      this.sessionName = "";
      this.editSessioinId = "";
    },
    // 创建或更新会话
    async createSession(index) {
      if (!this.sessionName.trim()) {
        this.$message.warning("会话名称不能为空");
        return;
      }

      try {
        const payload = { name: this.sessionName };
        if (index === 0) {
          // 新建会话
          createSession(payload).then((response) => {
            if (response.code === 200) {
              this.createSessionDialogVisible = false;
              this.$message.success("会话创建成功");
              this.getSessionList().then(() => {
                // 切换到新创建的会话
                const newSession = this.sessions.find(
                  (s) => s.name === this.sessionName
                );
                if (newSession) {
                  this.switchSession(newSession.id);
                }
              });
            } else {
              this.$message.error("会话创建失败");
            }
          });
        } else {
          // 更新会话
          updataSession(payload, this.editSessioinId).then((response) => {
            if (response.code === 200) {
              this.getSessionList();
              this.editSessioinId = "";
              this.updateSessionDialogVisible = false;
              this.$message.success("会话更新成功");
            } else {
              this.$message.error("会话更新失败");
            }
          });
        }
        this.sessionName = "";
      } catch (error) {
        this.$message.error("请求失败，请稍后重试");
      }
    },
    switchSession(id) {
      if (this.currentSessionId === id) {
        return;
      }
      this.currentSessionId = id;
      // 更新当前会话名称
      const currentSession = this.sessions.find((s) => s.id === id);
      this.currentSessionName = currentSession
        ? currentSession.description
        : "会话名称";
      this.messages = []; // 清空消息列表
      this.getCharList();
    },
    // 处理会话操作（编辑/删除）
    handleCommand(sessionId, command) {
      if (command === "edit") {
        this.editSessioinId = sessionId;
        // 填充当前会话名称
        const session = this.sessions.find((s) => s.id === sessionId);
        if (session) {
          this.sessionName = session.description;
        }
        this.updateSessionDialogVisible = true;
      } else if (command === "delete") {
        this.deleteSession(sessionId);
      }
    },
    // 删除会话
    deleteSession(sessionId) {
      this.$confirm("确定要删除这个会话吗?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          try {
            const params = { ids: sessionId };
            delSession(params).then((response) => {
              if (response.code === 200) {
                this.$message.success("删除成功");
                this.getSessionList();
                // 如果删除的是当前会话，重置当前会话ID
                if (this.currentSessionId === sessionId) {
                  this.currentSessionId = null;
                  this.currentSessionName = "会话名称";
                  this.messages = [];
                }
              } else {
                this.$message.error("删除失败");
              }
            });
          } catch (error) {
            this.$message.error("请求失败，请稍后重试");
          }
        })
        .catch(() => {
          this.$message.info("已取消删除");
        });
    },
    // 获取聊天列表
    getCharList() {
      try {
        if (!this.currentSessionId) {
          return;
        }

        const params = { sessionId: this.currentSessionId };

        getChatList(params).then((response) => {
          if (
            response.code === 200 &&
            response.data &&
            response.data.data &&
            response.data.data[0]
          ) {
            const messages = response.data.data[0].messages || [];
            this.messages = messages.map((msg) => ({
              type: msg.role === "assistant" ? "bot" : "user",
              content: msg.content,
              imageData: msg.image,
              Mstype: msg.Mstype || "text",
            }));
          } else {
            throw new Error(response.msg || "消息列表获取失败");
          }
        });
      } catch (error) {
        console.error("获取聊天列表失败:", error);
        this.$message.error(error.message || "请求失败，请稍后重试");
      }
    },
    // 获取会话列表
    getSessionList() {
      return new Promise((resolve, reject) => {
        try {
          getSessions({ require: "list" }).then((response) => {
            if (response.code === 200 && response.data && response.data.data) {
              this.sessions = response.data.data.map((res) => ({
                id: res.id,
                name: res.name,
                description: res.name,
              }));
              // 如果有会话但没有选中的会话，默认选中第一个
              if (this.sessions.length > 0 && !this.currentSessionId) {
                this.currentSessionId = this.sessions[0].id;
                this.currentSessionName = this.sessions[0].name;
                this.getCharList();
              }
              resolve();
            } else {
              this.$message.error("会话列表查询失败");
              reject();
            }
          });
        } catch (error) {
          this.$message.error("请求失败，请稍后重试");
          reject();
        }
      });
    },
    // 上传文件前处理
    handleBeforeUpload(file) {
      const isLt50M = file.size / 1024 / 1024 < 50;
      if (!isLt50M) {
        this.$message.error("文件大小不能超过 50MB!");
        return false;
      }
      file.url = URL.createObjectURL(file);
      this.uploadFileList.push(file);
      this.uploadedFiles = [...this.uploadFileList, ...this.imageFileList];
      return false;
    },
    // 上传图片前处理
    handleImageBeforeUpload(file) {
      const isImage = file.type.startsWith("image/");
      if (!isImage) {
        this.$message.error("只能上传图片文件!");
        return false;
      }
      const isLt10M = file.size / 1024 / 1024 < 10;
      if (!isLt10M) {
        this.$message.error("图片大小不能超过 10MB!");
        return false;
      }
      file.url = URL.createObjectURL(file);
      this.imageFileList.push(file);
      this.uploadedFiles = [...this.uploadFileList, ...this.imageFileList];
      return false;
    },
    // 移除文件
    handleFileRemove(file) {
      URL.revokeObjectURL(file.url);
      this.uploadFileList = this.uploadFileList.filter(
        (f) => f.name !== file.name
      );
      this.uploadedFiles = [...this.uploadFileList, ...this.imageFileList];
    },
    // 移除图片
    handleImageRemove(file) {
      URL.revokeObjectURL(file.url);
      this.imageFileList = this.imageFileList.filter(
        (f) => f.name !== file.name
      );
      this.uploadedFiles = [...this.uploadFileList, ...this.imageFileList];
    },
    // 发送消息
    async sendMessage() {
      if (!this.inputMessage.trim() && this.uploadedFiles.length === 0) {
        return;
      }

      if (!this.currentSessionId) {
        this.$message.warning("请先创建或选择一个会话");
        return;
      }

      this.sending = true;
      let timeoutId;

      try {
        // 构建消息内容
        const messageContent = {
          text: this.inputMessage.trim(),
          files: this.uploadedFiles.map((file) => ({
            name: file.name,
            url: file.url,
            type: file.type,
          })),
        };

        // 添加用户消息到界面
        if (messageContent.text) {
          this.messages.push({
            type: "user",
            content: messageContent.text,
            Mstype: "text",
          });
        }

        // 添加文件消息到界面
        if (messageContent.files.length > 0) {
          for (const file of messageContent.files) {
            this.messages.push({
              type: "user",
              content: `发送${
                file.type?.startsWith("image/") ? "图片" : "文件"
              }: ${file.name}`,
              fileInfo: {
                name: file.name,
                url: file.url,
                type: file.type,
              },
              Mstype: file.type?.startsWith("image/") ? "image" : "file",
            });
          }
        }

        // 立即清空输入框和文件列表（关键修改）
        this.inputMessage = "";
        this.uploadedFiles = [];
        this.uploadFileList = [];
        this.imageFileList = [];

        // 添加加载消息
        this.messages.push({ type: "loading", content: "" });

        // 发送到后端
        const payload = {
          question: messageContent.text || "",
          files: messageContent.files,
          session_id: this.currentSessionId,
          stream: "false",
        };

        const controller = new AbortController();
        timeoutId = setTimeout(() => {
          controller.abort();
        }, 60000);

        const response = await Chat(payload);
        if (response.code === 200) {
          // 移除加载消息
          if (this.messages.at(-1)?.type === "loading") {
            this.messages.pop();
          }

          if (response.data?.data?.answer) {
            // 添加带打字效果的回复
            this.addBotMessageWithTypingEffect(response.data.data.answer);
          } else {
            console.warn("Response success but no answer:", response);
          }
        } else {
          throw new Error(response.msg || "请求失败");
        }
      } catch (error) {
        console.error("发送消息失败:", error);
        this.$message.error(error.message || "发送失败，请稍后重试");

        if (this.messages.at(-1)?.type === "loading") {
          this.messages.pop();
        }

        if (error.message.includes("超时")) {
          await this.getCharList();
        }
      } finally {
        clearTimeout(timeoutId);
        this.sending = false;
        this.scrollToBottom();
      }
    },
    // 添加带打字效果的bot消息
    addBotMessageWithTypingEffect(content) {
      // 创建一个空消息用于展示打字效果
      const messageId = Date.now();
      this.messages.push({
        id: messageId,
        type: "bot",
        content: "", // 初始为空
        Mstype: "text",
        typing: true, // 标记为正在打字
      });

      this.scrollToBottom();

      // 打字效果实现
      let index = 0;
      const typingSpeed = 20; // 打字速度，毫秒
      const formattedContent = this.formatRagflowText(content);

      const typingInterval = setInterval(() => {
        // 找到当前消息并更新内容
        const msgIndex = this.messages.findIndex((msg) => msg.id === messageId);
        if (msgIndex === -1) {
          clearInterval(typingInterval);
          return;
        }

        // 逐字添加内容
        index++;
        this.messages[msgIndex].content = formattedContent.substring(0, index);

        // 完成打字
        if (index >= formattedContent.length) {
          clearInterval(typingInterval);
          this.messages[msgIndex].typing = false;
        }

        this.scrollToBottom();
      }, typingSpeed);
    },
    // 滚动到最新消息
    scrollToBottom() {
      this.$nextTick(() => {
        const messageList = this.$refs.messageList;
        if (messageList) {
          messageList.scrollTop = messageList.scrollHeight;
        }
      });
    },

    // 图片预览
    previewImage(file) {
      if (file.url) {
        const h = this.$createElement;
        this.$msgbox({
          title: "图片预览",
          message: h("img", {
            attrs: {
              src: file.url,
              style: "max-width: 100%; max-height: 500px;",
            },
          }),
          showCancelButton: false,
          confirmButtonText: "关闭",
        });
      }
    },
    formatRagflowText(text) {
      if (!text) return "";
      // 处理文本格式
      text = text.replace(/^---$/gm, "<hr>");
      text = text.replace(/^### (.*)$/gm, "<h3>$1</h3>");
      text = text.replace(/^## (.*)$/gm, "<h2>$1</h2>");
      text = text.replace(/^# (.*)$/gm, "<h1>$1</h1>");
      text = text.replace(/\*\*(.*?)\*\*/g, "<b>$1</b>");
      text = text.replace(/^[-*] (.*)$/gm, "<li>$1</li>");
      text = text.replace(/\n/g, "<br>");
      if (text.includes("<li>")) {
        text = text.replace(/(<li>.*<\/li>)/gs, "<ul>$1</ul>");
      }
      return text;
    },
  },
  watch: {
    messages() {
      this.$nextTick(() => {
        const messageList = this.$refs.messageList;
        if (messageList) {
          messageList.scrollTop = messageList.scrollHeight;
        }
      });
    },
  },
};
</script>

<style scoped>
/* 引入示例的样式 */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: "PingFang SC", "Microsoft YaHei", sans-serif;
}

/* 加载消息的容器样式（继承Bot消息的布局） */
.message-loading {
  align-self: flex-start; /* 和Bot消息对齐 */
}
.message-loading .avatar {
  background: #e6f7ff; /* 和Bot头像背景一致 */
}
.message-loading .message-content {
  background: white; /* 和Bot消息背景一致 */
  border-bottom-left-radius: 4px; /* 和Bot消息圆角一致 */
}

/* 加载动画：闪烁的省略号 */
.loading-indicator {
  display: flex;
  align-items: center;
}
.dot-flash {
  display: inline-block;
  width: 8px;
  height: 8px;
  margin: 0 2px;
  border-radius: 50%;
  background-color: #409eff; /* 主色，和Bot消息一致 */
  animation: dotFlash 1s infinite;
}
.dot-flash:nth-child(2) {
  animation-delay: 0.2s;
}
.dot-flash:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes dotFlash {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.2;
  }
}

.avatar-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
}

/* 单独指定问题图标，确保生效 */
::v-deep .fa-brain,
::v-deep .fa-layer-group,
::v-deep .fa-robot {
  font-family: "Font Awesome 6 Free" !important;
  font-weight: 900 !important;
}

.template-button {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* 调整图标大小和颜色的优先级 */
.font-awesome-icon {
  font-size: 20px !important; /* 覆盖size属性，更灵活 */
  color: #4285f4 !important; /* 覆盖color属性 */
}

body {
  background-color: #f0f2f5;
  height: 100vh;
  overflow: hidden;
}

.chat-container {
  display: flex;
  height: 90vh;
  max-width: 1800px;
  margin: 0 auto;
  box-shadow: 0 0 30px rgba(0, 0, 0, 0.1);
  background-color: #fff;
}

/* 左侧面板 */
.left-panel {
  width: 260px;
  background: linear-gradient(135deg, #1e5799 0%, #207cca 100%);
  color: white;
  display: flex;
  flex-direction: column;
  position: relative;
  z-index: 10;
  box-shadow: 2px 0 10px rgba(0, 0, 0, 0.1);
}

.header {
  padding: 24px 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.app-name {
  font-size: 20px;
  font-weight: 600;
  display: flex;
  align-items: center;
}

.app-name i {
  margin-right: 10px;
  font-size: 24px;
}

.template-icon {
  font-size: 20px;
  cursor: pointer;
  transition: all 0.3s ease;
  padding: 8px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.1);
}

.template-icon:hover {
  background: rgba(255, 255, 255, 0.2);
  transform: rotate(15deg);
}

.button-container {
  padding: 20px 15px;
}

.oval-button {
  width: 100%;
  border-radius: 24px;
  height: 44px;
  background: rgba(255, 255, 255, 0.15);
  border: none;
  color: white;
  font-size: 16px;
  font-weight: 500;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  justify-content: center;
}

.oval-button i {
  margin-right: 8px;
}

.oval-button:hover {
  background: rgba(255, 255, 255, 0.25);
  transform: translateY(-2px);
}

.session-container {
  flex: 1;
  padding: 10px;
  overflow: hidden;
  position: relative;
}

.session-title {
  padding: 10px 15px;
  font-size: 14px;
  color: rgba(255, 255, 255, 0.7);
}

.session-list {
  list-style: none;
}

.session-item {
  padding: 12px 15px;
  border-radius: 8px;
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: rgba(255, 255, 255, 0.1);
  cursor: pointer;
  transition: all 0.25s ease; /* 统一过渡效果 */
}

.session-item:hover {
  background: rgba(255, 255, 255, 0.15);
}

/* 历史会话选中状态高亮样式 */
.session-item.active {
  background: rgba(255, 255, 255, 0.3);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  font-weight: 500;
  transform: translateX(2px);
}
/* 选中状态下的文字颜色 */
.session-item.active .session-name {
  color: #ffffff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
/* 优化悬停效果与选中状态的区分 */
.session-item:not(.active):hover {
  background: rgba(255, 255, 255, 0.15);
}

.session-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
}

.session-actions {
  opacity: 0;
  transition: opacity 0.2s;
}

.session-item:hover .session-actions {
  opacity: 1;
}

/* 右侧聊天区域 */
.right-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  background-color: #f5f7fa;
  overflow: hidden;
}

/* 聊天视图的整体容器 */
.chat-wrapper {
  display: flex;
  flex-direction: column;
  height: 100%; /* 占满右侧面板高度 */
}

.chat-header {
  background: white;
  padding: 16px 24px;
  border-bottom: 1px solid #ebeef5;
  display: flex;
  align-items: center;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
}

.chat-title {
  font-size: 18px;
  font-weight: 600;
  color: #303133;
}

.chat-content {
  flex: 1;
  padding: 24px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.message {
  max-width: 80%;
  margin-bottom: 24px;
  display: flex;
  animation: fadeIn 0.3s ease;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.message-bot {
  align-self: flex-start;
}

.message-user {
  align-self: flex-end;
}

.avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: #e6f7ff;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 12px;
  flex-shrink: 0;
}

.message-content {
  padding: 12px 16px;
  border-radius: 18px;
  line-height: 1.5;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
  white-space: pre-wrap; /* 保留换行符并自动换行 */
}

.message-bot .message-content {
  background: white;
  border-bottom-left-radius: 4px;
  /* 添加淡入动画 */
  animation: fadeIn 0.5s ease forwards;
  opacity: 0;
}
@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
/* 打字效果的光标样式 */
::v-deep .text.typing::after {
  content: "|";
  animation: blink 1s step-end infinite;
  margin-left: 3px;
}

@keyframes blink {
  from,
  to {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
}

.message-user .message-content {
  background: #207cca;
  color: white;
  border-bottom-right-radius: 4px;
}

.chat-input {
  padding: 16px 24px;
  background: white;
  border-top: 1px solid #ebeef5;
  flex-shrink: 0; /* 禁止收缩 */
  box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.03); /* 增加阴影区分层级 */
}

.input-area {
  display: flex;
  flex-direction: column;
  background: white;
  border-radius: 8px;
  border: 1px solid #dcdfe6;
  overflow: hidden;
  box-sizing: border-box;
  /* padding: 12px;  */
}

.input-area:focus-within {
  border-color: #409eff;
}

textarea {
  position: relative;
  top: -83px;
  flex: 1;
  width: 100%;
  height: 100px;
  border: none;
  border-radius: 8px;
  padding: 16px;
  font-size: 15px;
  resize: none;
  outline: none;
  box-sizing: border-box;
}
textarea:focus {
  border-color: #409eff;
}

.send-button {
  width: 48px;
  height: 48px;
  border: none;
  background: transparent;
  cursor: pointer;
  transition: transform 0.2s;
  /* color: #1a4b80; */
}

.send-button:disabled {
  background: #c0c4cc;
  cursor: not-allowed;
  box-shadow: none;
}

/* 模板管理浮层 */
.template-overlay {
  position: absolute;
  left: 260px;
  top: 0;
  height: 100%;
  background: white;
  width: 300px;
  box-shadow: 5px 0 15px rgba(0, 0, 0, 0.1);
  z-index: 5;
  transition: transform 0.4s ease, opacity 0.4s ease;
  transform: translateX(-20px);
  opacity: 0;
  pointer-events: none;
  padding: 24px;
  display: flex;
  flex-direction: column;
}

.template-overlay.visible {
  transform: translateX(0);
  opacity: 1;
  pointer-events: auto;
}

.template-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
  padding-bottom: 16px;
  border-bottom: 1px solid #ebeef5;
}

.template-title {
  font-size: 18px;
  font-weight: 600;
  color: #303133;
}

.template-actions {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.template-button {
  padding: 16px;
  border-radius: 8px;
  background: #f5f7fa;
  border: 1px dashed #dcdfe6;
  display: flex;
  align-items: center;
  cursor: pointer;
  transition: all 0.3s;
}

.template-button:hover {
  background: #e6f7ff;
  border-color: #409eff;
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(64, 158, 255, 0.2);
}

/* .template-button i {
  font-size: 24px;
  color: #409eff;
  margin-right: 12px;
  width: 40px;
  height: 40px;
  background: rgba(64, 158, 255, 0.1);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
} */

.template-button span {
  font-size: 16px;
  font-weight: 500;
  color: #303133;
}

.template-button p {
  font-size: 13px;
  color: #909399;
  margin-top: 4px;
}

.template-list {
  margin-top: 24px;
  flex: 1;
  overflow-y: auto;
}

.template-item {
  padding: 12px;
  border-radius: 8px;
  margin-bottom: 10px;
  background: white;
  border: 1px solid #ebeef5;
  display: flex;
  align-items: center;
  cursor: pointer;
  transition: all 0.2s;
}

.template-item:hover {
  border-color: #409eff;
  background: #f5f7fa;
}

.template-icon-sm {
  width: 36px;
  height: 36px;
  background: rgba(64, 158, 255, 0.1);
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 12px;
  color: #409eff;
  font-size: 18px;
}

.template-info {
  flex: 1;
}

.template-name {
  font-weight: 500;
  margin-bottom: 4px;
}

.template-date {
  font-size: 12px;
  color: #909399;
}

.placeholder-text {
  color: #c0c4cc;
  text-align: center;
  padding: 40px 0;
  font-size: 14px;
}

.floating-notification {
  position: fixed;
  bottom: 20px;
  right: 20px;
  background: white;
  padding: 16px 24px;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  display: flex;
  align-items: center;
  z-index: 1000;
  animation: slideIn 0.5s ease;
}

@keyframes slideIn {
  from {
    transform: translateY(20px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

.notification-icon {
  width: 36px;
  height: 36px;
  background: #e6f7ff;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 12px;
  color: #409eff;
  font-size: 18px;
}

.notification-content h3 {
  font-size: 16px;
  margin-bottom: 4px;
}

.notification-content p {
  font-size: 14px;
  color: #606266;
}

.close-notification {
  margin-left: 20px;
  cursor: pointer;
  color: #c0c4cc;
}

.close-notification:hover {
  color: #409eff;
}

/* 输入框 */
.input-row {
  width: 100%;
  margin-top: 10px;
  position: relative; /* 相对定位，确保按钮基于输入框定位 */
  display: flex;
  align-items: flex-end; /* 按钮与输入框底部对齐 */
  gap: 0px;
  box-sizing: border-box;
}
.textarea-container {
  position: relative;
  width: 100%;
}
.upload-area {
  margin-bottom: 15px;
}

.upload-container {
  display: flex;
  gap: 16px;
  margin-bottom: 36px;
}

.files-grid {
  margin-top: 8px;
}

.grid-container {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* .grid-item {
  .file-box {
    display: flex;
    align-items: center;
    padding: 4px 8px;
    background-color: #f5f7fa;
    border: 1px solid #dcdfe6;
    border-radius: 2px;
    height: 24px;
    min-width: 140px;
    max-width: 240px;

    &:hover {
      background-color: #f5f7fa;
      .file-actions {
        opacity: 1;
      }
    }

    .file-icon {
      margin-right: 6px;
      i {
        font-size: 14px;
        color: #909399;
      }
    }

    .file-name {
      flex: 1;
      font-size: 12px;
      color: #606266;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      margin-right: 6px;
    }

    .file-actions {
      opacity: 0;
      transition: opacity 0.2s;
      i {
        font-size: 14px;
        color: #909399;
        cursor: pointer;
        &:hover {
          color: #f56c6c;
        }
      }
    }
  }
} */

/* 文件列表动画 */
.file-list-enter-active,
.file-list-leave-active {
  transition: all 0.2s ease;
}

.file-list-enter-from,
.file-list-leave-to {
  opacity: 0;
  transform: translateY(-4px);
}

/* 弹框按钮容器 */
.dialog-footer {
  text-align: right;
}

/* 基础按钮样式 */
.dialog-btn {
  border-radius: 24px;
  width: 55px;
  height: 32px;
  background: linear-gradient(135deg, #1e5799 0%, #207cca 100%);
  border: none;
  color: white;
  font-size: 15px;
  padding: 0 24px;
  margin-right: 0px;
  padding-left: 12px;
  transition: all 0.3s ease;
}

.dialog-btn:hover {
  /* 悬停时加深渐变 */
  background: linear-gradient(135deg, #1a4b80 0%, #1a69b7 100%);
  transform: translateY(-2px);
}

.dialog-btn-primary {
  background: linear-gradient(135deg, #1e5799 0%, #207cca 100%);
  color: white;
}

.dialog-btn-primary:hover {
  /* 悬停时加深蓝色渐变 */
  background: linear-gradient(135deg, #1a4b80 0%, #1a69b7 100%);
}

.component-header .back-btn {
  background: linear-gradient(135deg, #1e5799 0%, #207cca 100%);
  color: white;
  /* 适当加大尺寸，避免内容拥挤 */
  padding: 6px 12px; /* 上下6px 左右16px，兼顾图标和文字 */
  min-width: 50px;
  height: 36px;
  /* 圆角更圆润，增强亲和力 */
  border-radius: 9px;
  /* 轻微阴影提升层次感 */
  box-shadow: 0 2px 4px rgba(140, 163, 187, 0.2);
  /* 图标与文字间距 */

  /* 文字样式 */
  font-size: 15px;
  /* font-weight: 500; */
  /* 过渡动画，让交互更流畅 */
  transition: all 0.2s ease;
  margin: 3px; /* 保持与其他元素的间距 */
}
.component-header h3 {
  margin: 5px;
  font-size: 17px;
  color: #2597cd;
}
</style>
